home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource4 / 203_01 / yam11.asm < prev    next >
Assembly Source File  |  1979-12-31  |  14KB  |  560 lines

  1. PAGE ,132
  2. TITLE 'YAM11: YAM TERMIO ASSMELBY ROUTINES'
  3. ;DATE ( 7 nov 85)
  4.  
  5. ; SMALL MODEL
  6. .xlist
  7. INCLUDE \LC\S\DOS.MAC
  8. .list
  9.  
  10. ; interrupt vectors
  11. ser0        equ    0ch    ;serial 0 interrupt
  12. ser1        equ    0bh    ;serial 1 interrupt
  13. break        equ    01bh    ;break interrupt
  14. cntlc        equ    023h    ;control-c handler
  15. lpt        equ    017h    ;printer status
  16.  
  17. ; monitor functions
  18. get_status    equ    02h    ;get printer status
  19.  
  20. ; dos functions
  21. commint        equ    14h    ;monitor serial I/O
  22. dos        equ    21h    ;ms-dos vector
  23. dcio        equ    6h    ;dos direct console i/o
  24. get_vector    equ    35h    ;get interrupt vector
  25. set_vector    equ    25h    ;set interrupt vector
  26.  
  27. ; i/o port addresses
  28. cntl8259    equ    20h    ;control port
  29. mask8259    equ    21h    ;interrupt mask register
  30.  
  31. ; offsets to rest of ports
  32. intenreg    equ    1    ;interrupt enable
  33. intidreg    equ    2    ;interrupt identication
  34. lcreg        equ    3    ;line control
  35. modctlreg    equ    4    ;modem control
  36. linestreg    equ    5    ;line status
  37. modstreg    equ    6    ;modem status
  38.  
  39. ; masks and data equates
  40. charrdy        equ    01h    ;character ready
  41. cr        equ    0dh
  42. eoi        equ    20h    ;non-specific eoi command
  43. idisable    equ    0f7h    ;serial int disable
  44. ienable        equ    08H    ;serial int enable
  45. lf        equ    0ah
  46. mask3        equ    08h    ;int3 disable mask
  47. mask4        equ    010h    ;int4 disable mask
  48. mon_conout    equ    14    ;funtion code
  49. page_0        equ    0    ;page to output char to
  50. rts        equ    02h    ;rts on mask
  51. rtsoff        equ    0fdh    ;rts off mask
  52. rxdmask        equ    01h    ;interrupt on rx data ready
  53. txrdy        equ    20h    ;transmitter ready
  54. unmask3        equ    0f7h    ;int7 enable mask for 8259
  55. unmask4        equ    0efh    ;int4 enable mask for 8259
  56. xoff        equ    013h    ;^s
  57.  
  58. ;=======================================================
  59.     dseg
  60.  
  61. errflg    dw    0        ;error flag for init comm
  62. lowater    dw    0        ;copy of LOWWATER
  63. termflg    db    0        ;true if in terminal mode
  64.  
  65. ; global variables
  66. extrn    Dport:word        ;actual data port #
  67. extrn    bufst:word        ;pointer to buffer start
  68. extrn    bufend:word        ;pointer to buffer end
  69. extrn    bufcq:word        ;buffer pointer for modem
  70. extrn    bufcdq:word        ;buffer pointer for console
  71. extrn    Ignrx:word        ;Flag which says to throw away chars in rxnono
  72. extrn    rxnono:word        ;pointer to buffer of characters to ignore
  73. extrn    Timeout:word        ;timeout before next char rx
  74. extrn    Nfree:word        ;number of free bytes in buffer
  75. extrn    overrun:word        ;set if buffer overflows
  76. extrn    Wrapped:word        ;indicates buffer pointer has looped
  77. extrn    Xoffflg:word        ;flag indicating Xoff was sent
  78.     endds
  79.  
  80. ;=======================================================
  81.     pseg
  82.  
  83. ;storage locations in code segment
  84. brk    dd    0        ;break vector storage
  85. ctlc    dd    0        ;control-c vector storage 
  86.  
  87. ;*******************************************************
  88. ; return used for break interrupt handlers
  89. cc_hand    proc    far
  90.     iret
  91. cc_hand    endp
  92.  
  93.  
  94. ;*******************************************************
  95. ; cause an INT3 for entry into debuggers.
  96. ; calling sequence:
  97. ;    dbgint();
  98.  
  99. public  dbgint
  100. dbgint    proc    near
  101.     int    3
  102.     ret
  103. dbgint    endp
  104.  
  105.  
  106. public init_com
  107. init_com proc near
  108. ;*******************************************************
  109. ; initialze interrupt vectors for serial port.  This will ensure
  110. ; all characters from the serial port are not missed.  It also resets
  111. ; the control-c and break vector so they will not cause an abort back
  112. ; to the operating system, leaving interrupt vectors in a unknown state.
  113. ; calling sequence:
  114. ;    init_comm(LOWWATER)
  115. ;        where LOWWATER is the number of bytes left in the buffer
  116. ;        at which XOFF is set to the modem.
  117.  
  118.     cld            ;auto increment
  119.     push    bp        ;save bp
  120.     mov    bp,sp
  121.     mov    ax,[bp+4]    ;LOWWATER is parmeter to this routine
  122.     mov    lowater,ax
  123.     cmp    si,bx        ;check for buffer overflow
  124.     pop    bp        ;done with passed parameters
  125.     push    es        ;save es for caller(required by lattice c or
  126.                 ;very strange things result
  127.     push    ds        ;we muck with ds
  128.     cli            ;disable interrupts when setting vectors
  129.  
  130. ; save the break interrupt vector.  Save area is in code
  131. ; segment, thus the segment over-rides.
  132.     mov    ah,get_vector
  133.     mov    al,break
  134.     int    dos
  135.     mov    word ptr cs:brk,bx    ;vector returned in es:bx
  136.     mov    word ptr cs:brk+2,es
  137.  
  138. ; save the contol-c interrupt vector
  139.     mov    ah,get_vector
  140.     mov    al,cntlc
  141.     int    dos
  142.     mov    word ptr cs:ctlc,bx    ;vector returned in es:bx
  143.     mov    word ptr cs:ctlc+2,es
  144.  
  145. ; modify old break vector to point to our handler.  It must
  146. ; return with an iret instruction.  Since ds is changed to cs,
  147. ; mov will function properly with no segment override.
  148.     push    cs
  149.     pop    ds            ;set ds=code segment
  150.     mov    ah,set_vector
  151.     mov    al,break        ;break interrupt vector
  152.     mov    dx,offset cc_hand    ;pointer in ds:dx
  153.     int    dos
  154.  
  155. ; modify old control-c vector to point to our handler.
  156.     mov    ah,set_vector
  157.     mov    al,cntlc        ;break interrupt vector
  158.     mov    dx,offset cc_hand    ;pointer in ds:dx
  159.     int    dos
  160.  
  161.     pop    ds
  162.     pop    es        ;restore es for caller
  163.     sti            ;re-enable system interrupts
  164.     ret    2        ;one passed parmeter
  165. init_com endp
  166.  
  167.  
  168. public setport
  169. setport    proc    near
  170. ;*******************************************************
  171. ; set the interrupt vector for the requested comm port.
  172. ; only ports 0 and 1 are supported due to they are the only
  173. ; ones which support interrupts on most systems.
  174. ; calling sequence:
  175. ;    setport(port_num);
  176.  
  177.     cli
  178.     push    bp        ;save bp
  179.     mov    bp,sp
  180.     mov    bx,[bp+4]    ;get modem port number
  181.     push    ds
  182.     push    bx
  183.  
  184. ; modify serial interrupt vector to point to its handler
  185.     push    cs
  186.     pop    ds        ;vector set to ds:dx
  187.     mov    ah,set_vector
  188.     cmp    bx,1        ;serial port #1 is at int 3
  189.     jz    por1
  190.     mov    al,ser0        ;serial #0 vector
  191.     jmp    short setvec
  192. por1:    mov    al,ser1        ;serial #1 interrupt vector
  193. setvec:    mov    dx,offset ser_int
  194.     int    dos
  195.  
  196. ;enable 8259 mask
  197.     in    al,mask8259    ;get mask
  198.     pop    bx        ;check port #
  199.     cmp    bx,1        ;serial port #1 is at int 3
  200.     jz    epor1
  201.     and    al,unmask4    ;enable int4
  202.     jmp    short emask
  203. epor1:    and    al,unmask3    ;enable int3
  204. emask:    out    mask8259,al
  205.     pop    ds
  206.     pop    bp
  207.     sti            ;re-enable system interrupts
  208.     ret    2        ;one passed parmeter
  209. setport endp
  210.  
  211.  
  212. public resport
  213. resport proc    near
  214. ;*******************************************************
  215. ; reset the interrupt vector for the requested comm port.
  216. ; only ports 0 and 1 are supported due to they are the only
  217. ; ones which support interrupts on most systems.
  218. ; calling sequence:
  219. ;    resport(port_num);
  220.  
  221.     cli
  222.     push    bp        ;save bp
  223.     mov    bp,sp
  224.     mov    bx,[bp+4]    ;get modem port number
  225.  
  226. ; mask comm interrupt
  227.     in    al,mask8259    ;get mask
  228.     cmp    bx,1        ;serial port #1 is at int 3
  229.     jz    dpor1
  230.     or    al,mask4    ;disable int4
  231.     jmp    short dmask
  232. dpor1:    or    al,mask3    ;disable int3
  233. dmask:    out    mask8259,al
  234.  
  235. ; disable trisate buffer for comm interrupt
  236.     mov    dx,[Dport]
  237.     add    dx,modctlreg
  238.     in    al,dx
  239.     and    al,idisable and rtsoff
  240.     out    dx,al        ;set out2 line false
  241.  
  242.     pop    bp
  243.     sti            ;re-enable system interrupts
  244.     ret    2        ;one passed parmeter
  245. resport endp
  246.  
  247.  
  248. public enblcm
  249. enblcm    proc    near
  250. ;*******************************************************
  251. ; unmask comm interrupt
  252. ; enable bit for receive data interrupt and tristate buffer to allow
  253. ; interrupts from ACIA.  Some of the MSDOS commands such as INT 14
  254. ; seem to muck with these bits.  Mode is true if in terminal mode otherwise 0.
  255. ; Mode sets a flag used by the interrupt routine.
  256. ; calling sequence:
  257. ;    enblcm(mode);
  258.  
  259.     cli
  260.     push    bp        ;save bp
  261.     mov    bp,sp
  262.     mov    al,[bp+4]    ;get termflag
  263.     mov    termflg,al
  264.     mov    dx,[Dport]
  265.     add    dx,intenreg    ;enable serial interrupts
  266.     mov    al,rxdmask
  267.     out    dx,al
  268.  
  269. ; enable trisate buffer so interrupts can get to bus
  270.     mov    dx,[Dport]
  271.     add    dx,modctlreg
  272.     in    al,dx
  273.     or    al,ienable or rts
  274.     out    dx,al        ;set out2 line true
  275.     pop    bp
  276.     sti
  277.     ret    2        ;one passed parameter
  278. enblcm    endp
  279.  
  280.  
  281. public dsblcm
  282. dsblcm    proc    near
  283. ;*******************************************************
  284. ; reset interrupt enable register of acia
  285. ; calling sequence:
  286. ;    dsblcm();
  287.  
  288.     cli
  289.     mov    dx,[Dport]
  290.     add    dx,intenreg    ;offset to enable register
  291.     mov    al,0        ;disable serial interrupts
  292.     out    dx,al
  293.     sti
  294.     ret
  295. dsblcm    endp
  296.  
  297.  
  298. public res_comm
  299. res_comm proc    near
  300. ;*******************************************************
  301. ; reset interrupt vectors set up in init_comm
  302. ; calling sequence:
  303. ;    res_comm();
  304.  
  305.     cld            ;auto increment
  306.     cli            ;disable interrupts when resetting vectors
  307.     push    ds        ;we muck with ds again
  308.  
  309. ; restore break vector
  310.     mov    ah,set_vector
  311.     mov    al,break    ;break interrupt vector
  312.     mov    dx,word ptr brk    ;pointer in ds:dx
  313.     mov    ds,word ptr brk+2
  314.     int    dos
  315.  
  316. ; restore control-c vector
  317.     mov    ah,set_vector
  318.     mov    al,cntlc    ;contol-c interrupt vector
  319.     mov    dx,word ptr ctlc;pointer in ds:dx
  320.     mov    ds,word ptr ctlc+2
  321.     int    dos
  322.  
  323. ; re-enable system interrupts
  324.     pop    ds
  325.     sti
  326.     ret
  327. res_comm endp
  328.  
  329.  
  330. public ser_int
  331. ser_int proc    far
  332. ;*******************************************************
  333. ; serial interrupt routine.  This routine gets characters
  334. ; from the modem and stuffs them into a circular buffer.
  335. ; Global flag Wrapped is set if buffer pointer wrap around
  336. ; calling sequence:
  337. ;    none.  this is an interrupt routine
  338.  
  339.     push    ax
  340.     push    dx
  341.     push    di
  342.     push    ds
  343.     mov    ax,dgroup    ;ds may be wrong
  344.     mov    ds,ax
  345.     mov    dx,[Dport]
  346.     add    dx,linestreg
  347.     in    al,dx        ;line status
  348.     test    al,charrdy    ;check data ready
  349.     jz    seoi        ;nope, so long
  350.     mov    dx,[Dport]
  351.     in    al,dx        ;read character
  352.     mov    di,ds:bufcq    ;get bufferpointer
  353.     mov    [di],al        ;save char
  354.     inc    di        ;bump pointer
  355.     cmp    termflg,0    ;terminal mode does more
  356.     jz    noterm
  357.     call    termstuff
  358.  
  359. ; if(bufcq >= bufend)
  360. ; {
  361. ;     Wrapped=TRUE;
  362. ;    bufcq=bufst;
  363. ; }
  364. noterm:    cmp    di,ds:bufend    ;check for end of buffer
  365.     jl    serdone
  366.     mov    di,ds:bufst    ;bufcq=bufst
  367.     mov    ds:Wrapped,0ffh    ;Wrapped = true
  368. serdone:mov    ds:bufcq,di    ;update pointer
  369.  
  370. seoi:    mov    al,eoi
  371.     out    cntl8259,al    ;set eoi to controller
  372.     pop    ds
  373.     pop    di
  374.     pop    dx
  375.     pop    ax
  376. intret:    sti            ;re-enable interrupts
  377.     iret
  378. ser_int    endp
  379.  
  380.  
  381. termstuff proc    near
  382. ;*******************************************************
  383. ; this procedure contains stuff to do in the terminal mode.
  384. ; in file transfer mode, this should not be called.
  385. ; on entry ax contains last char read, and di contains pointer to
  386. ; next free buffer location.
  387.  
  388. ;if (!Ignrx)
  389. ;    bufcq++;
  390. ;else
  391. ;if(!index(*bufcq, rxnono))
  392. ;    bufcq++;
  393. ;
  394.     push    si        ;part of interrupt save
  395.     cmp    ds:Ignrx,0
  396.     jz    tnfree        ;go test Nfree
  397.     mov    si,offset ds:rxnono
  398. tloop:    mov    ah,[si]        ;scan for match
  399.     cmp    ah,0        ;end of string
  400.     jz    tnfree
  401.     cmp    ah,al
  402.     jz    found
  403.     inc    si        ;next char
  404.     jmp    tloop
  405. found:    dec    di        ;set free buffer pointer back one
  406.  
  407. ; Timeout=0;
  408. ; if(--Nfree == LOWWATER)
  409. ;     MOCHAR(Xoffflg=TRUE);
  410. ; else if(Nfree==0)
  411. ;     overrun = TRUE;
  412. ;
  413. tnfree:    mov    ds:timeout,0    ;Timeout = 0
  414.     dec    ds:Nfree    ;number of free bytes -= 1
  415.     mov    ax,ds:Nfree    ;check for < LOWWATER
  416.     cmp    ax,0        ;test overflow
  417.     jnz    chklow
  418.     mov    ds:overrun,1    ;overflow = true
  419.  
  420. chklow:    cmp    ax,ds:lowater
  421.     jne    done        ;Nfree grows down
  422.     mov    ds:Xoffflg,1    ;set flag indicating xoff was sent
  423.     mov    ax,XOFF        ;send Xoff only Nfree=lowater
  424.     push    ax
  425.     call    mochr        ;send Xoff to modem
  426. done:    pop    si
  427.     ret
  428. termstuff    endp
  429.  
  430.  
  431.  
  432. public mirdy
  433. mirdy    proc    near
  434. ;*******************************************************
  435. ; if character has come in, bufcq and bufcdq will be different
  436. ; if not, zero will be returned in ax, with the zero flag set.
  437. ; calling sequence:
  438. ;    if (mirdy());
  439.  
  440.     mov    ax,ds:bufcq
  441.     sub    ax,[ds:bufcdq]
  442.     ret
  443. mirdy    endp
  444.  
  445.  
  446. public michr
  447. michr     proc    near
  448. ;*******************************************************
  449. ; get a character out of the modem input buffer and return in
  450. ; ax register.  Pointer will be wrapped around to start of buffer
  451. ; if it goes past the end.
  452. ; calling sequence:
  453. ;    ch = michr();
  454.  
  455.     mov    si,ds:bufcdq    ;char out pointer
  456.     mov    al,[si]        ;get char
  457.     mov    ah,0        ;make integer
  458.     inc    si        ;next buffer location
  459.     cmp    si,ds:bufend    ;check for end of buffer
  460.     jl    midone        ;dont reset pointer
  461.     mov    si,ds:bufst    ;pointer wrapped around
  462. midone:    mov    ds:bufcdq,si    ;bufcdq++
  463.     ret
  464. michr    endp
  465.  
  466.  
  467. public cnsrdy
  468. cnsrdy    proc    near
  469. ;*******************************************************
  470. ; console ready function.  If a key has been pressed, the zero flag will
  471. ; be reset.  If not, clear ax and return.  This routine is used to
  472. ; bypass the DOS ^C handling.
  473. ; calling sequence:
  474. ;    if (cnsrdy());
  475.  
  476.     mov    ah,1        ;console status function
  477.     int    16h        ;key board i/o thru monitor
  478.     jnz    char        ;char rx
  479. nochar:    xor    ax,ax        ;clear ax and set zero flag
  480. char:    ret
  481. cnsrdy    endp
  482.  
  483.  
  484. public     cnsin
  485. cnsin    proc    near
  486. ;*******************************************************
  487. ; get a char from the console.  char is returned in al, with
  488. ; with keycode in ah.
  489. ; calling sequence:
  490. ;    ch = cnsin();
  491.  
  492.     mov    ah,0
  493.     int    16h
  494.     ret
  495. cnsin    endp
  496.  
  497.  
  498. public    mochr
  499. mochr    proc    near
  500. ;*******************************************************
  501. ; output char modem port.  Char is passed on stack as 
  502. ; first argument.  This routine is used rather than the
  503. ; monitor because the stupid IBM bios resets the interrupt enable
  504. ; line to the interrupt driver.  
  505. ; calling sequence:
  506. ;    mochr(ch);
  507.     
  508.     push    bp        ;save bp
  509.     mov    bp,sp
  510.     mov    dx,[Dport]    ;wait for txrdy
  511.     add    dx,linestreg
  512. moloop:    in    al,dx
  513.     test    al,txrdy    ;wait for hardware
  514.     jz    moloop
  515.     mov    al,[bp+4]    ;get char to output
  516.     mov    dx,[Dport]    ;transmit port
  517.     out    dx,al
  518.     pop    bp
  519.     ret    2        ;clean stack
  520. mochr    endp
  521.  
  522.  
  523. public    cochar
  524. cochar    proc    near
  525. ;*******************************************************
  526. ; output char on stack to console.  Use direct console output
  527. ; to bypass control-c, while allowing ansi driver to function
  528. ; calling sequence:
  529. ;    cochar(ch);
  530.  
  531.     push    bp        ;save bp
  532.     mov    bp,sp
  533.     mov    dl,[bp+4]    ;get char to output
  534.     mov    ah,dcio        ;direct console i/o
  535.     int    dos
  536.     pop    bp
  537.     ret    2        ;clean stack
  538. cochar    endp
  539.  
  540. public    prtrdy
  541. prtrdy    proc    near
  542. ;*******************************************************
  543. ; returns with ax=0 if printer is busy, otherwise ax <> 0
  544. ; calling sequence:
  545. ;    if prtrdy();
  546.  
  547.     mov    ah,get_status    ;function code
  548.     mov    dx,0        ;printer port
  549.     int    lpt        ;monitor printer status function
  550.     and    ah,11111001b    ;mask off unused bits
  551.     cmp    ah,10010000b    ;test for ready and select
  552.     je    rdy        ;if =, printer is ready
  553.     mov    ax,0        ;if not ready, return false
  554. rdy:    ret
  555. prtrdy    endp
  556.  
  557.     endps
  558.  
  559.     end
  560.